/*
 * CteplException.java
 *
 * Copyright (c) 2008 CTEPL, Inc.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of Ctepl, Inc.
 * ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the
 * license agreement you entered into with Ctepl.
 *
 */

package com.ctepl.common.exception;

import java.io.*;

/**
 * The top level exception thrown from the the com.syrrx.util package.  This is thrown as the
 * generic exception when there is not specific information about the exception.  In
 * general this exception will contain a cause which is the actual cause of the exception,
 * such as SQLException etc. that represent another domain/class of exception.  All other
 * exceptions should subclass this when more specific information about the
 * exception needs to be returned to the client.
 */
 /*
  * DEVELOPER NOTE: Update this once jdk1.4 is in use.  Exceptions have been updated and
  *  standardized to handle this type of nested exception with a cause. - jvig
  */
public class CteplException extends Exception {

    /** A sub-exception that may have been the ultimate cause of this exception, may be null */
    private Throwable _cause;

    /**
     * This is private to force non-default construction: make user enter more
     * info for this exception, at least a message.
     */
    private CteplException() {
    }

    /**
     * Construct with an cause to wrap by this exception
     *
     * @param wrappedEx The original exception that caused the problem, saved internally.
     */
    public CteplException(Throwable cause) {
        super(snagWrapeeText(cause));
        _cause = cause;
    }

   /**
     * Construct with a message but no cause exception
     *
     * @param wrappedEx The original exception that caused the problem, saved internally.
     */
    public CteplException(String message) {
        super(message);
    }

	/**
	 * Wrap a caught exception as a cause and provide a specific message to inform the user
	 * what the problem may be.
	 */
	public CteplException(String message, Throwable cause)
	{
		super(message + "\n  Nested exception: " + snagWrapeeText(cause));
		_cause = cause;
	}

    /**
     * Get the cause of the exception (this method will be standard in 1.4b3)
     *
     * @return Throwable the original exception/cause
     */
    public Throwable getCause() {
        Throwable cause = this; // default to this exception as the cause

        // If wrapping another exception then get it as the cause...
        if (_cause != null) {
            cause = _cause;
        }

        return cause;
    }

    /**
     * helper to pull out some (very verbose) text, useful for wrapped exceptions to be able
     * to show their full stackTrace, even when wrapped in ServerException
     */
    private static String snagWrapeeText(Throwable cause)
    {
        // kinda lot of overhead.  Makes debugging easyer (until exception in 1.4 is ready)

        // snag some text data, return it.
        StringWriter strWriter = new StringWriter();
        PrintWriter dumpOut = new PrintWriter(strWriter, false);
        cause.printStackTrace(dumpOut);
        dumpOut.println("---- end nested exception stack trace ----");
        return strWriter.toString();
    }
}